//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include "aura.h"
#include "wince.h"
#include "private.h"

AURA_API AuraMutex_Create(
        /* [out] */ Aura_Handle * phMutex)
{
    HANDLE hMutex = NULL;

    assert(NULL != phMutex);

    hMutex = CreateMutexW(NULL, FALSE, NULL);
    if(NULL == hMutex) {
        goto E_FAIL_EXIT;
    }
    *phMutex = (Aura_Handle)hMutex;

    return AURA_NOERROR;

E_FAIL_EXIT:
    return GetLastAuraECode();
}

AURA_API AuraMutex_Lock(
        /* [in] */ Aura_Handle hMutex,
        /* [in] */ Aura_Millisecond32 timeOut,
        /* [out] */ Aura_WaitResult * pResult)
{
    DWORD dwRes = 0;

    assert(NULL != hMutex);

    dwRes = WaitForSingleObject((HANDLE)hMutex, (DWORD)timeOut);
    if (WAIT_FAILED == dwRes) {
        goto E_FAIL_EXTI;
    }
    else if (WAIT_OBJECT_0 == dwRes) {
        *pResult = Aura_WaitResult_OK;
    }
    else if (WAIT_TIMEOUT == dwRes) {
        *pResult = Aura_WaitResult_TimedOut;
    }
#if _DEBUG
    else {
        assert(0);
    }
#endif

    return AURA_NOERROR;

E_FAIL_EXTI:
    return GetLastAuraECode();
}

AURA_API AuraMutex_Unlock(
        /* [in] */ Aura_Handle hMutex)
{
    BOOL bSuccess = FALSE;

    assert(NULL != hMutex);

    bSuccess = ReleaseMutex((HANDLE)hMutex);
    if (!bSuccess) {
        goto E_FAIL_EXIT;
    }

    return AURA_NOERROR;

E_FAIL_EXIT:
    return GetLastAuraECode();
}

AURA_API AuraMutex_Destroy(
        /* [in] */ Aura_Handle hMutex)
{
    assert(NULL != hMutex);

    CloseHandle((HANDLE)hMutex);
    return AURA_NOERROR;
}

AURA_API AuraCriticalSection_Create(
        /* [out] */ Aura_Handle * phCriticalSection)
{
    LPWIN_CRITICAL_SECTION pCriticalSection;

    assert(NULL != phCriticalSection);

    pCriticalSection = (LPWIN_CRITICAL_SECTION)
                Aura_malloc(sizeof(WIN_CRITICAL_SECTION));
    if (NULL == pCriticalSection) {
        return AURA_E_OUT_OF_MEMORY;
    }

    InitializeCriticalSection(pCriticalSection);
    *phCriticalSection = (Aura_Handle)pCriticalSection;

    return AURA_NOERROR;
}

AURA_API AuraCriticalSection_Enter(
        /* [in]  */ Aura_Handle hCriticalSection)
{
    assert(NULL != hCriticalSection);
    EnterCriticalSection((LPWIN_CRITICAL_SECTION)hCriticalSection);

    return AURA_NOERROR;
}

AURA_API AuraCriticalSection_Leave(
        /* [in]  */ Aura_Handle hCriticalSection)
{
    assert(NULL != hCriticalSection);
    LeaveCriticalSection((LPWIN_CRITICAL_SECTION)hCriticalSection);

    return AURA_NOERROR;
}

AURA_API AuraCriticalSection_Destroy(
        /* [in]  */ Aura_Handle hCriticalSection)
{
    assert(NULL != hCriticalSection);
    DeleteCriticalSection((LPWIN_CRITICAL_SECTION)hCriticalSection);
    Aura_free((void *)hCriticalSection);

    return AURA_NOERROR;
}

